# -*- coding: utf-8 -*-

import requests
from rabbitmq import RabbitConnection
from rabbitmq.config import *


def dead_queue(channel):

    def callback(ch, method, properties, body):
        # 回调函数, 处理消息队列中的消息
        # 设置手动应答
        ch.basic_ack(delivery_tag=method.delivery_tag)
        resp = requests.post(url=run_base_schedule_api, data={'request_id': body})
        if resp.status_code == 200:
            return 200
        print(f'执行定时任务request_id[{body}]返回结果: 失败')

    # 声明交换机
    exchange_arguments = {
        'x-delayed-type': 'direct'
    }
    channel.exchange_declare(
        exchange=dead_exchange, durable=False, exchange_type=delay_exchange_type, arguments=exchange_arguments,
    )
    # 声明队列, 如果指定的queue不存在，则会创建一个queue, 如果已经存在 则不会做其他动作
    # 官方推荐, 每次使用时都可以加上这句, 这样生产者和消费者就没有必要的先后启动顺序了
    channel.queue_declare(queue=dead_queue_name, durable=False)
    # 建立绑定关系（交换机、队列、路由key）
    channel.queue_bind(exchange=dead_exchange, queue=dead_queue_name, routing_key=dead_routing_key)

    # prefetch_count表示接收的消息数量，当我接收的消息没有处理完（用basic_ack标记消息已处理完毕）之前不会再接收新的消息了
    # 还有就是这个设置必须在basic_consume之上，否则不生效
    # 这种情况必须关闭自动应答ack，改成手动应答。
    # 使用basicQos(prefetch_count=1) 限制每次只发送不超过1条消息到同一个消费者，消费者必须手动反馈告知队列，才会发送下一个.
    channel.basic_qos(prefetch_count=1)

    # 告诉rabbitmq，用callback来接收消息
    channel.basic_consume(
        dead_queue_name,
        callback,
        # 指定为False，表示取消自动应答，交由回调函数手动应答
        auto_ack=False
    )
    return channel


if __name__ == '__main__':
    rabbit = RabbitConnection()
    channel = rabbit.get_connection()
    consuming = dead_queue(channel)
    print('开始监听')
    try:
        consuming.start_consuming()
    except KeyboardInterrupt:
        consuming.stop_consuming()
        rabbit.connection.close()
        print('close')
